﻿using System;
using System.Collections.Generic;
using Zeta.Common;

namespace KadalaSpree.XCore
{
    public static partial class X
    {
        
        public static class Actors
        {
            #region Fields

            private static readonly Dictionary<int, XActor> ActorsById = new Dictionary<int, XActor>();

            #endregion

            #region Common Actors

            public static XActor Kadala
            {
                get { return GetActorByName(ActorName.Kadala); }
            }

            public static XActor Orek
            {
                get { return GetActorByName(ActorName.Orek); }
            }

            public static XActor Waypoint
            {
                get { return GetActorByName(ActorName.Waypoint); }
            }

            public static XActor Enchantress
            {
                get { return GetActorByName(ActorName.Enchantress); }
            }

            public static XActor NephalemObelisk
            {
                get { return GetActorByName(ActorName.NephalemObelisk); }
            }

            public static XActor HearthPortal
            {
                get { return GetActorByName(ActorName.HearthPortal); }
            }

            public static XActor Stash
            {
                get { return GetActorByName(ActorName.Stash); }
            }

            public static XActor Jeweler
            {
                get { return GetActorByName(ActorName.Jeweler); }
            }

            public static XActor Blacksmith
            {
                get { return GetActorByName(ActorName.Blacksmith); }
            }

            #endregion

            #region Methods

            public static XActor GetActorById (int id)
            {
                if (!ActorsById.ContainsKey(id))
                {                
                    var actor = new XActor(id);                
                    ActorsById.Add(id, actor);
                }
                else
                {
                    if (!ActorsById[id].IsValid)
                    {
                        //Logger.Log("Actor {0} isn't valid, updating", ActorsById[id].ActorName);
                        ActorsById[id].Update();
                    }
                }
                return ActorsById[id];
            }

            public static XItem GetItemById (int id)
            {
                if (!ActorsById.ContainsKey(id))
                {
                    var item = new XItem(id);
                    ActorsById.Add(id, item);
                }
                else
                {
                    if (!ActorsById[id].IsValid)
                    {
                        ActorsById[id].Update();
                    }
                }
                return (XItem) ActorsById[id];
            }

            public static XActor GetActorByName (ActorName name)
            {
                if (!XLookup.Actors.ActorNameAndId.ContainsKey(name))
                {
                    Logger.Instance.Log("actor name not found in lookup '{0}'", name);
                }
                var id = XLookup.Actors.ActorNameAndId[name];
                return GetActorById(id);
            }

            public static XItem GetMysteryItemBySlotType (VendorSlotType type)
            {
                var id = 0;
                try
                {
                    id = XLookup.Actors.Vendors.MysterySlotTypeAndId[type];
                }
                catch (Exception ex)
                {
                    X.Logger.Instance.Log("GetMysteryItemBySlotType Exception Id={0} Type={1} Exception={2}", id, type, ex);
                }
                return GetItemById(id);
            }

            public static void InteractWith (ActorName name)
            {            
                XActor actor = GetActorByName(name);

                if (!actor.IsValid || Player.IsTransitioning) return;

                Logger.Instance.Log("Interacting with {0}", name);

                actor.Interact();
            }

            #endregion


        }

    }    
}